/*
 * Copyright 2020-2024 Typelevel
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cats.effect

import cats.effect.std.Console

import scala.scalajs.js
import scala.scalajs.js.{Promise, Thenable}

private[effect] abstract class IOCompanionPlatform { this: IO.type =>

  def blocking[A](thunk: => A): IO[A] =
    apply(thunk)

  private[effect] def interruptible[A](many: Boolean, thunk: => A): IO[A] = {
    val _ = many
    apply(thunk)
  }

  def interruptible[A](thunk: => A): IO[A] = interruptible(false, thunk)

  def interruptibleMany[A](thunk: => A): IO[A] = interruptible(true, thunk)

  def suspend[A](hint: Sync.Type)(thunk: => A): IO[A] = {
    val _ = hint
    apply(thunk)
  }

  def fromThenable[A](iot: IO[Thenable[A]]): IO[A] =
    asyncForIO.fromThenable(iot)

  def fromThenableCancelable[A](iot: IO[(Thenable[A], IO[Unit])]): IO[A] =
    asyncForIO.fromThenableCancelable(iot)

  def fromPromise[A](iop: IO[Promise[A]]): IO[A] =
    asyncForIO.fromPromise(iop)

  def fromPromiseCancelable[A](iop: IO[(Promise[A], IO[Unit])]): IO[A] =
    asyncForIO.fromPromiseCancelable(iop)

  def realTimeDate: IO[js.Date] = asyncForIO.realTimeDate

  @deprecated("Not implemented for Scala.js. On Node.js consider using fs2.io.stdin.", "3.4.0")
  def readLine: IO[String] =
    Console[IO].readLine
}
